package com.artfii.fluentsql.core.tools;

import java.util.*;

/**
 * Func :
 *
 * FROM beetlsql
 */
public class StringKit {
    public static final String EMPTY = "";

    public static final int INDEX_NOT_FOUND = -1;

    public static final String[] EMPTY_STRING_ARRAY = new String[0];


    static  String lineSeparator = System.getProperty("line.separator", "\n");

    // 首字母转小写
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder())
                .append(Character.toLowerCase(s.charAt(0)))
                .append(s.substring(1)).toString();
    }

    // 首字母转大写
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder())
                .append(Character.toUpperCase(s.charAt(0)))
                .append(s.substring(1)).toString();
    }

    // 大写字母前面加上下划线并转为全小写
    public static String toUnderline(String came) {
        if(null== came || came.isEmpty()) return came;
        String r = null;
        char[] chars = came.toCharArray();
        StringBuilder temp = new StringBuilder(chars.length + 5);
        for (int i = 0; i < chars.length; i++) {
            if(Character.isUpperCase(chars[i]) && i>0){
                temp.append("_");
            }
            temp.append(Character.toLowerCase(chars[i]));
        }
        r = temp.toString();
        temp = null;
        return r;
    }

    /**
     * 下划线转为驼峰拼写
     * @param underscore
     * @return
     */
    public static String toCamel(String underscore) {
        if(null== underscore || underscore.isEmpty()) return underscore;
        char[] chars = underscore.toCharArray();
        int write=-1,len=chars.length;
        boolean upper=false;
        for (int read = 0; read < len; ++read) {
            char c = chars[read];
            if('_'==c){
                upper = true;
                continue;
            }
            if(upper){
                upper = false;
                chars[++write]=Character.toUpperCase(c);
            } else {
                chars[++write]=Character.toLowerCase(c);
            }
        }
        return new String(chars, 0, ++write);
    }

    /**
     * 删除下划线并且转为全小写
     * @param sourceStr
     * @return
     */
    public static String delSpellStyle(String sourceStr) {
        if(null== sourceStr || sourceStr.isEmpty()) return sourceStr;
        char[] chars = sourceStr.toCharArray();
        int len=chars.length;
        StringBuffer r = new StringBuffer(len);
        for (int read = 0; read < len; ++read) {
            char c = chars[read];
            if('_'==c){
                continue;
            }
            r.append(Character.toLowerCase(c));

        }
        return r.toString();
    }


    /**
     * 去空格
     * @param str
     * @return
     */
    public static String trimAllWhitespace(String str) {
        if (!((CharSequence) str != null && ((CharSequence) str).length() > 0)) {
            return str;
        }
        StringBuilder sb = new StringBuilder(str);
        int index = 0;
        while (sb.length() > index) {
            if (Character.isWhitespace(sb.charAt(index))) {
                sb.deleteCharAt(index);
            }
            else {
                index++;
            }
        }
        return sb.toString();
    }

    /**
     * 左边去空格
     * @param str
     * @return
     */
    public static String trimLeft(String str) {
        if (isEmpty(str)) {
            return str;
        }
        int index = 0;
        while (str.length() > index) {
            if (!Character.isWhitespace(str.charAt(index))) {
                str = str.substring(index,str.length());
                break;
            }
            index++;
        }
        return str;
    }

    public static String substringBeforeLast(String str, String separator) {
        if (isEmpty(str) || isEmpty(separator)) {
            return str;
        }
        int pos = str.lastIndexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return str;
        }
        return str.substring(0, pos);
    }

    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    public static boolean endsWith(String str, String suffix, boolean ignoreCase) {
        if (str == null || suffix == null) {
            return (str == null && suffix == null);
        }
        if (suffix.length() > str.length()) {
            return false;
        }
        int strOffset = str.length() - suffix.length();
        return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
    }

    public static boolean startsWith(String str, String prefix, boolean ignoreCase) {
        if (str == null || prefix == null) {
            return (str == null && prefix == null);
        }
        if (prefix.length() > str.length()) {
            return false;
        }
        return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
    }


    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (separator == null) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }


    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }


    /**
     * 判断一个 Object 是否为空，不包含集合对象的判断
     *
     * @param obj need to determine the object
     * @author larrykoo
     * @return
     */
    public static boolean isNullOrEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }
        return false;
    }

    /**
     * 严格判断一个 Object 是否为空，包括对象为 null，字符串长度为0，集合类，Map 为 empty 的情况
     *
     * @param obj
     * @author larrykoo
     * @return
     */
    public static boolean isNullOrEmptyObject(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }

        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }
        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
        }
        return false;
    }

    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

    public static String[] split(String str, char separatorChar) {
        return splitWorker(str, separatorChar, false);
    }

    public static String beforeLast(String str, char separatorChar) {
        int pos = str.lastIndexOf((int) separatorChar);
        return pos == -1 ? "" : str.substring(0, pos);
    }

    private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
        // Performance tuned for 2.0 (JDK1.4)

        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len == 0) {
            return EMPTY_STRING_ARRAY;
        }
        List list = new ArrayList(len+1);
        int i = 0, start = 0;
        boolean match = false;
        boolean lastMatch = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match || preserveAllTokens) {
                    list.add(str.substring(start, i));
                    match = false;
                    lastMatch = true;
                }
                start = ++i;
                continue;
            }
            lastMatch = false;
            match = true;
            i++;
        }
        if (match || (preserveAllTokens && lastMatch)) {
            list.add(str.substring(start, i));
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * 把数组或列表值转换成 [1,2,3]==>'1','2','3'
     * 方便组装 SQL 的 IN 语句
     * @param val
     * @return
     */
    public static Object listOrArrayToLine(Object val) {
        if (null == val) return null;
        if (val.getClass().isArray()) {
            StringBuffer _temp = new StringBuffer(100);
            Object[] vv = (Object[]) val;
            for (Object o : vv) {
                _temp.append("'").append(o).append("'");
                _temp.append(",");
            }
            _temp.deleteCharAt(_temp.length() - 1);
            String v = _temp.toString();
            _temp = null;
            return v;
        }
        if (val instanceof Collection) {
            StringBuffer _temp = new StringBuffer(100);
            Collection list = (Collection) val;
            for (Object o : list) {
                _temp.append("'").append(o).append("'");
                _temp.append(",");
            }
            _temp.deleteCharAt(_temp.length() - 1);
            String v = _temp.toString();
            _temp = null;
            return v;
        }
        return val;
    }

    public static boolean isNumber(String str) {
        for (char s : str.toCharArray()) {
            boolean isNum = String.valueOf(s).matches("[0-9]+");
            if (!isNum) {
                return false;
            }
        }
        return true;
    }

    /**
     * 通过简单indexOf查找位置，indexOf方法本身基于char数组变量来定位
     * @param source 源字符串
     * @param searchString 匹配字符串
     * @param replaceString 目标字符串
     * @return 返回结果
     */
    public static String replaceAll(String source, String searchString, String replaceString) {

        if (source == null) {
            return null;
        }

        if (null== searchString || searchString.length()==0) {
            return source;
        }

        if (replaceString == null) {
            replaceString = "";
        }
        int len = source.length();
        int sl = searchString.length();
        int rl = replaceString.length();
        int length;
        if (sl == rl) {
            length = len;
        } else {
            int c = 0;
            int s = 0;
            int e;
            while ((e = source.indexOf(searchString, s)) != -1) {
                c++;
                s = e + sl;
            }
            if (c == 0) {
                return source;
            }
            length = len - (c * (sl - rl));
        }

        int s = 0;
        int e = source.indexOf(searchString, s);
        if (e == -1) {
            return source;
        }
        StringBuffer sb = new StringBuffer(length);
        while (e != -1) {
            sb.append(source.substring(s, e));
            sb.append(replaceString);
            s = e + sl;
            e = source.indexOf(searchString, s);
        }
        e = len;
        sb.append(source.substring(s, e));
        return sb.toString();
    }

    public static String replace(String str, String patten, String replacement) {
        return replace(str, patten, replacement, 0);
    }

    public static String replace(String str, String patten, String replacement, int pos) {
        if(null==str || str.isEmpty()) return str;
        int len = str.length();
        int plen = patten.length();
        StringBuilder _temp = new StringBuilder(len);
        int lastPos = 0;
        do {
            pos = str.indexOf(patten, lastPos);
            if (pos != -1) {
                _temp.append(str, lastPos, pos);
                _temp.append(replacement);
                lastPos = pos + plen;
            }else {
                return str;
            }
        } while (str.indexOf(patten, lastPos) > 0);
        _temp.append(str, lastPos, len);
        str = _temp.toString();
        _temp = null;
        return str;
    }

    public static int countFind(String orcStr, String patten,int startPos,int endPos) {
        if(null==orcStr || orcStr.isEmpty()) return 0;
        int pos=0,count=0;
        do{
            pos = orcStr.indexOf(patten,startPos);
            if(pos == -1){
                return count;
            }else {
                count++;
            }
            startPos = pos+1;
        }while (pos != endPos);
        return count;
    }


    public static void main(String[] args) {
        System.err.println(trimAllWhitespace(" fsdfsd sdfds fsd "));
        System.err.println(trimLeft("     from user"));

        String u = "User_name_sHr";

        String came = toCamel(u);
        System.err.println(came);
        System.err.println(toUnderline(came));

        System.err.println(delSpellStyle(u));
        System.err.println(replace(u, "name", "alice"));

        String orcStr ="UserName=:userName and Age=:age";

        System.err.println(countFind(orcStr,":",0,9));
    }



}
